package cn.org.seventh.web.common;

import java.io.File;

import javax.servlet.ServletContext;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.ServletContextAware;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.util.WebUtils;

/**
 * 能够被代理的CustomWebApplicationObjectSupport
 * 行为同spring自带的WebApplicationObjectSupport 这里仅仅去掉了所有方法的final标识
 * 使得该类方法在子类中被代理后该类方法也能被代理 从而使得该类的子类行为和原有类保持一致
 * 如果不去掉final标识会使得用代理类的引用调用非代理方法不能获取代理前的原始值 注意在被代理过得方法中的this引用的是代理前的对象
 * 未代理的final方法中的this引用是代理类对象 非final的方法中均可以this表示代理前对象 为了避免错误均采用一致行为
 * 在fianl标识的方法中凡是要保持和代理前行为一致可能需要改变this引用属性方式 解决办法为使用get set 如果原有属性没有 可能会添加访问方法
 * Convenient superclass for application objects running in a
 * WebApplicationContext. Provides getWebApplicationContext, getServletContext,
 * and getTempDir methods.
 * 
 * @author Juergen Hoeller
 * @since 28.08.2003
 * @see cn.org.seventh.web.common.CustomApplicationObjectSupport
 * @see cn.org.seventh.web.common.CustomWebApplicationObjectSupport
 * @see org.springframework.context.support.ApplicationObjectSupport
 */
public abstract class CustomWebApplicationObjectSupport extends
		CustomApplicationObjectSupport implements ServletContextAware {
	private ServletContext servletContext;

	public void setServletContext(ServletContext servletContext) {
		this.servletContext = servletContext;
	}

	/**
	 * Overrides the base class behavior to enforce running in an
	 * ApplicationContext. All accessors will throw IllegalStateException if not
	 * running in a context.
	 * 
	 * @see #getApplicationContext()
	 * @see #getMessageSourceAccessor()
	 * @see #getWebApplicationContext()
	 * @see #getServletContext()
	 * @see #getTempDir()
	 */
	protected boolean isContextRequired() {
		return true;
	}

	/**
	 * Return the current application context as WebApplicationContext.
	 * <p>
	 * <b>NOTE:</b> Only use this if you actually need to access
	 * WebApplicationContext-specific functionality. Preferably use
	 * <code>getApplicationContext()</code> or
	 * <code>getServletContext()</code> else, to be able to run in
	 * non-WebApplicationContext environments as well.
	 * 
	 * @throws IllegalStateException
	 *             if not running in a WebApplicationContext
	 * @see #getApplicationContext()
	 */
	protected WebApplicationContext getWebApplicationContext()
			throws IllegalStateException {
		ApplicationContext ctx = getApplicationContext();
		if (!(ctx instanceof WebApplicationContext)) {
			throw new IllegalStateException(
					"WebApplicationObjectSupport instance ["
							+ this
							+ "] does not run in a WebApplicationContext but in: "
							+ ctx);
		}
		return (WebApplicationContext) getApplicationContext();
	}

	/**
	 * Return the current ServletContext.
	 * 
	 * @throws IllegalStateException
	 *             if not running within a ServletContext
	 */
	protected ServletContext getServletContext() throws IllegalStateException {
		if (this.servletContext != null) {
			return this.servletContext;
		}
		return getWebApplicationContext().getServletContext();
	}

	/**
	 * Return the temporary directory for the current web application, as
	 * provided by the servlet container.
	 * 
	 * @return the File representing the temporary directory
	 * @throws IllegalStateException
	 *             if not running within a ServletContext
	 * @see org.springframework.web.util.WebUtils#getTempDir(javax.servlet.ServletContext)
	 */
	protected File getTempDir() throws IllegalStateException {
		return WebUtils.getTempDir(getServletContext());
	}

}
